import notificationService from './notificationService';
import logger from '../components/utils/logger';

/**
 * 错误类型枚举
 * 定义系统中可能遇到的各类错误类型
 */
export enum ErrorType {
  VALIDATION = 'validation',
  NETWORK = 'network',
  IPC = 'ipc',
  CALCULATION = 'calculation',
  FILE = 'file',
  UNKNOWN = 'unknown'
}

/**
 * 错误信息映射
 * 为每种错误类型提供默认的错误消息
 */
const errorMessageMap: Record<ErrorType, string> = {
  [ErrorType.VALIDATION]: '数据验证错误',
  [ErrorType.NETWORK]: '网络连接错误',
  [ErrorType.IPC]: '进程通信错误',
  [ErrorType.CALCULATION]: '计算过程错误',
  [ErrorType.FILE]: '文件操作错误',
  [ErrorType.UNKNOWN]: '未知错误'
};

/**
 * 错误处理配置接口
 * 定义错误处理的可选配置项
 */
interface ErrorHandlerConfig {
  showNotification?: boolean;
  logError?: boolean;
  customMessage?: string;
}

/**
 * 默认错误处理配置
 */
const defaultConfig: ErrorHandlerConfig = {
  showNotification: true,
  logError: true
};

/**
 * 统一的错误处理服务
 * 提供一致的错误处理机制，包括错误日志记录和用户友好的错误消息展示
 * 支持多种错误类型和自定义处理选项
 */
export class ErrorHandlerService {
  /**
 * 处理错误的通用方法
 * @param error 错误对象
 * @param errorType 错误类型
 * @param config 错误处理配置
 */
  handleError(
    error: any,
    errorType: ErrorType = ErrorType.UNKNOWN,
    config: ErrorHandlerConfig = {}
  ): void {
    const mergedConfig = { ...defaultConfig, ...config };
    
    // 确保错误对象有效
    if (!error) {
      return;
    }
    
    // 提取错误消息
    const errorMessage = this.extractErrorMessage(error, errorType, mergedConfig.customMessage);
    
    // 记录错误日志
    if (mergedConfig.logError) {
      this.logError(error, errorType, errorMessage);
    }
    
    // 显示错误通知
    if (mergedConfig.showNotification) {
      notificationService.error(errorMessage);
    }
  }

  /**
 * 提取错误消息
 * 根据错误对象的结构提取或生成合适的错误消息
 * @param error 错误对象
 * @param errorType 错误类型
 * @param customMessage 自定义错误消息（可选）
 * @returns 格式化的错误消息
 */
  private extractErrorMessage(
    error: any,
    errorType: ErrorType,
    customMessage?: string
  ): string {
    // 优先使用自定义消息
    if (customMessage) {
      return customMessage;
    }
    
    // 根据错误类型和结构提取消息
    if (typeof error === 'string') {
      return error;
    }
    
    if (error?.message) {
      return error.message;
    }
    
    if (error?.error) {
      return error.error;
    }
    
    // 特殊处理 IPC 错误
    if (errorType === ErrorType.IPC && error?.code) {
      return `IPC调用失败: ${error.code}`;
    }
    
    // 特殊处理验证错误
    if (errorType === ErrorType.VALIDATION && error?.errorFields) {
      const validationErrors = error.errorFields
        .map((field: any) => field.errors.join('; '))
        .join('\n');
      return `数据验证失败: ${validationErrors}`;
    }
    
    // 返回默认错误消息
    return errorMessageMap[errorType];
  }

  /**
   * 记录错误日志
   * 使用日志服务记录错误信息，包括错误类型、消息和原始错误对象
   * @param error 错误对象
   * @param errorType 错误类型
   * @param errorMessage 格式化后的错误消息
   */
  private logError(error: any, errorType: ErrorType, errorMessage: string): void {
    // 使用共享的日志服务记录错误
    logger.error(`[${errorType.toUpperCase()}] ${errorMessage}`, {
      originalError: error,
      stack: (error instanceof Error) ? error.stack : undefined
    });
  }

  /**
   * 处理验证错误
   * 专门用于处理表单或数据验证失败的情况
   * @param error 错误对象
   * @param customMessage 自定义错误消息（可选）
   */
  handleValidationError(error: any, customMessage?: string): void {
    this.handleError(error, ErrorType.VALIDATION, { customMessage });
  }

  /**
   * 处理网络错误
   * 专门用于处理网络请求失败的情况
   * @param error 错误对象
   * @param customMessage 自定义错误消息（可选）
   */
  handleNetworkError(error: any, customMessage?: string): void {
    this.handleError(error, ErrorType.NETWORK, {
      customMessage: customMessage || '网络连接失败，请检查您的网络设置或稍后再试'
    });
  }

  /**
   * 处理 IPC 错误
   * 专门用于处理主进程与渲染进程通信失败的情况
   * @param error 错误对象
   * @param channel IPC通道名称（可选）
   * @param customMessage 自定义错误消息（可选）
   */
  handleIpcError(error: any, channel?: string, customMessage?: string): void {
    const ipcMessage = channel ? `通道 "${channel}" ` : '';
    this.handleError(error, ErrorType.IPC, {
      customMessage: customMessage || `IPC${ipcMessage}通信失败，请重启应用后重试`
    });
  }

  /**
   * 处理计算错误
   * 专门用于处理计算过程中出现的错误
   * @param error 错误对象
   * @param customMessage 自定义错误消息（可选）
   */
  handleCalculationError(error: any, customMessage?: string): void {
    this.handleError(error, ErrorType.CALCULATION, {
      customMessage: customMessage || '计算过程中发生错误，请检查输入参数是否正确'
    });
  }

  /**
   * 处理文件错误
   */
  handleFileError(error: any, operation: string, customMessage?: string): void {
    this.handleError(error, ErrorType.FILE, {
      customMessage: customMessage || `${operation}文件失败，请检查文件权限或稍后再试`
    });
  }
}

// 创建并导出默认的错误处理服务实例
export const errorHandlerService = new ErrorHandlerService();

export default errorHandlerService;